﻿using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;

namespace daStaticAnalyser.Analysers
{
    using daStaticAnalyser;
    using daBase.Objects;
    using daBase.Analyser;
    using daSyntaxAnalyser;
    using daSyntaxAnalyser.SyntaxTree;

    [AnalyserDefaultSettings("Мера Кафура", "test", 0, "test")]
    class KafurAnalyzer : BaseStaticAnalyser
    {
        private void GetData(ISyntaxTreeElement Element, bool InControlOperator)
        {
            if (Element == null)
                return;

            if (Element is StandartVariableExpressionElement)
            {
                String temp = Element.ToString();
                String[] strs = temp.Split('.');
                if (!temp.Contains("("))
                {

                    if (strs.Length > 1)
                    {
                        if (InControlOperator)
                        {
                            if (!Meth.fan_out.Contains(strs[0])) Meth.fan_out.Add(strs[0]);
                        }
                        else
                        {
                            if (!Meth.fan_in.Contains(strs[0])) Meth.fan_in.Add(strs[0]);
                        }
                    }
                }
                else
                {
                    int ind = temp.IndexOf('(');
                    String MethodName = temp.Substring(0, ind);
                    MethodInf temp1 = Methods.Find(s => s.Name == MethodName);
                    if (temp1 != null)
                    {
                        if (!temp1.fan_out.Contains(MethodName)) temp1.fan_out.Add(MethodName);
                        if (!Meth.fan_out.Contains(MethodName)) Meth.fan_in.Add(MethodName);
                    }
                }
            }
            else if (Element is AssignmentElement)
            {
                AssignmentElement Asse = Element as AssignmentElement;
                GetData(Asse.Variable, true);
                GetData(Asse.Expression, false);
                return;
            }

            foreach (ISyntaxTreeElement element in Element)
            {
                GetData(element, InControlOperator);
            }
        }

        List<MethodInf> Methods = new List<MethodInf>();
        public int fan_in;
        public int fan_out;
        MethodInf Meth;
        protected override void DoAnalyse(SyntaxTreeArgs e)
        {
            String MethodName = "";
            if (CheckMethod_GetName(e, out MethodName))
            {
                OuterMethodElement Method = e.Element as OuterMethodElement;
                fan_in = 0;
                fan_out = 0;
                int LSI = CalculateCountOperators(Method.Body);
                Meth = new MethodInf(MethodName, Method.StartInfo.File, Method.StartInfo.Line, LSI);
                GetData(Method.Body, false);                
                Methods.Add(Meth);
            }
        }

        protected override void DoFinishAnalyse(EventArgs e)
        {
            foreach (MethodInf inf in Methods)
            {
                int fan_in = inf.fan_in.Count;
                int fan_out = inf.fan_out.Count;
                float Length = inf.LSI;
                float I = Length * (fan_in * fan_out) * (fan_in * fan_out);

                AddMetric("Мера Кафура",
                            I,
                            inf.Name,
                            inf.File,
                            inf.Line);
            }
            Methods.Clear();
        }
    }
}
